package com.powernode.lambda.lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.function.*;

/**
 * 改进普通方法参数，添加函数式接口作为参数
 */
public class Lambda04 {
    public static void main(String[] args) {
        ArrayList<Integer> integers = new ArrayList<>();
        integers.add(1);
        integers.add(2);
        integers.add(3);
        integers.add(4);
        integers.add(5);
        List<Integer> rt1 = filterPlus(integers, number -> (number & 1) == 0);
        System.out.println(rt1);
        List<String> strings = mapPlus(integers, integer -> String.valueOf(integer));
        System.out.println(strings);
        consumePlus(integers,integer -> System.out.println(integer));
        System.out.println(supplyPlus(5, () -> ThreadLocalRandom.current().nextInt()));
    }
    static List<Integer> filter(List<Integer> list) {
        List<Integer> result = new ArrayList<>();
        for (Integer number : list) {
            // 筛选:判断是否是偶数，但以后可能改变筛选规则
            if ((number & 1) == 0) {
                result.add(number);
            }
        }
        return result;
    }

    /**
     * filter方法改进版，把函数式接口的对象传进去，即把判断规则传进去
     * (number & 1) == 0 ，变量为number，即有 (Integer number) -> (number & 1) == 0
     * 考虑到输入一个Integer类型参数，输入一个boolean类型的结果，因此用Predicate<Integer>
     * @param list
     * @param intPredicate
     * @return
     */
    static List<Integer> filterPlus(List<Integer> list, Predicate<Integer> intPredicate) {
        List<Integer> result = new ArrayList<>();
        for (Integer number : list) {
            // 筛选:判断是否是偶数，但以后可能改变筛选规则
            if (intPredicate.test(number)) {
                result.add(number);
            }
        }
        return result;
    }


    static List<String> map(List<Integer> list) {
        List<String> result = new ArrayList<>();
        for (Integer number : list) {
            // 转换:将数字转为字符电，但以后可能改变转换规则
            result.add(String.valueOf(number));
        }
        return result;
    }

    /**
     * map方法改进版，把函数式接口的对象传进去，即把判断规则传进去
     * String.valueOf(number) , (Integer number) -> String.valueOf(number)
     * 输入变量为Integer类型的number，输出String类型的结果，考虑用Function<Integer,String>
     * @param list
     * @return
     */
    static List<String> mapPlus(List<Integer> list, Function<Integer,String> function) {
        List<String> result = new ArrayList<>();
        for (Integer number : list) {
            // 转换:将数字转为字符串，但以后可能改变转换规则
            result.add(function.apply(number));
        }
        return result;
    }

    static void consume(List<Integer> list) {
        for (Integer number : list) {
            // 消费:打印，但以后可能改变转换规则
            System.out.println(number);
        }
    }

    /**
     * consume方法改进版，把函数式接口的对象传进去，即把判断规则传进去
     * System.out.println(number), (Integer number) -> System.out.println(number)
     * 输入变量为Integer类型的number，无输出结果，考虑用Consumer<Integer>
     * @param list
     */
    static void consumePlus(List<Integer> list, Consumer<Integer> consumer) {
        for (Integer number : list) {
            // 消费:打印，但以后可能改变转换规则
            consumer.accept(number);
        }
    }

    static List<Integer> supply(int count) {
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            result.add(ThreadLocalRandom.current().nextInt());
        }
        return result;
    }

    /**
     * supply方法改进版，把函数式接口的对象传进去，即把判断规则传进去
     * () -> result.add(ThreadLocalRandom.current().nextInt())
     * 无输入变量，有输出结果，考虑用supplier<Integer>
     * @param count
     * @return
     */
    static List<Integer> supplyPlus(int count,Supplier<Integer> supplier) {
        List<Integer> result = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            result.add(supplier.get());
        }
        return result;
    }

}
